package spotor.client.provider;

import java.util.ArrayList;
import java.util.Arrays;

import spotor.client.provider.SpotorContract.Plans;
import spotor.client.provider.SpotorDatabase.Tables;
import spotor.client.util.SelectionBuilder;
import android.content.ContentProvider;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentValues;
import android.content.Context;
import android.content.OperationApplicationException;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.util.Log;

public class SpotorProvider extends ContentProvider {
	private static final String TAG = "PlanProvider";
	private static final boolean LOGV = Log.isLoggable(TAG, Log.VERBOSE);

	private SpotorDatabase mOpenHelper;

	private static final UriMatcher sUriMatcher = buildUriMatcher();

	private static final int PLANS = 100;
	private static final int PLANS_ID = 101;

	private static final String MINE_XML = "text/xml";

	/**
	 * 
	 */
	private static UriMatcher buildUriMatcher() {
		final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
		final String authority = SpotorContract.CONTENT_AUTHORITY;

		matcher.addURI(authority, "plans", PLANS);
		matcher.addURI(authority, "plans/#", PLANS_ID);

		return matcher;
	}
	
	@Override
	public boolean onCreate() {
		// TODO Auto-generated method stub
		final Context context = getContext();
		mOpenHelper = new SpotorDatabase(context);
		return true;
	}
	
	@Override
	public String getType(Uri uri) {
		// TODO Auto-generated method stub
		final int match = sUriMatcher.match(uri);

		switch (match) {
		case PLANS:
			return Plans.CONTENT_TYPE;
		case PLANS_ID:
			return Plans.CONTENT_ITEM_TYPE;
		default:
			throw new UnsupportedOperationException("未知的uri:" + uri);
		}
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		if (LOGV)
			Log.v(TAG,
					"query(uri=" + uri + ", proj="
							+ Arrays.toString(projection) + ")");
		final SQLiteDatabase db = mOpenHelper.getReadableDatabase();

		final int match = sUriMatcher.match(uri);
		switch (match) {
		default: {
			final SelectionBuilder builder = buildExpandedSelection(uri, match);
			return builder.where(selection, selectionArgs).query(db,
					projection, sortOrder);
		}
		}

	}
	
	@Override
	public Uri insert(Uri uri, ContentValues values) {
		// TODO Auto-generated method stub
		if (LOGV)
			Log.v(TAG, "intsert (uri=" + uri + ", values=" + values.toString()
					+ ")");
		final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
		final int match = sUriMatcher.match(uri);
		switch (match) {
		case PLANS: {
			db.insertOrThrow(Tables.PLANS, null, values);
			return Plans.buildPlanUri(values.getAsString(Plans.PLAN_ID));
		}
		default: {
			throw new UnsupportedOperationException("Unknown uri:" + uri);
		}
		}
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		// TODO Auto-generated method stub
		if (LOGV)
			Log.v(TAG, "update(uri=" + uri + ", values=" + values.toString()
					+ ")");
		final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
		final SelectionBuilder builder = buildSimpleSelection(uri);
		return builder.where(selection, selectionArgs).update(db, values);
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		// TODO Auto-generated method stub
		if (LOGV)
			Log.v(TAG, "delete(uri=" + uri + ")");
		final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
		final SelectionBuilder builder = buildSimpleSelection(uri);
		return builder.where(selection, selectionArgs).delete(db);
	}

	private SelectionBuilder buildExpandedSelection(Uri uri, int match) {
		final SelectionBuilder builder = new SelectionBuilder();
		switch (match) {
		case PLANS: {
			return builder.table(Tables.PLANS);
		}
		case PLANS_ID: {
			final String planId = Plans.getPlanId(uri);
			return builder.table(Tables.PLANS).where(Plans.PLAN_ID + "=?",
					planId);
		}
		default: {
			throw new UnsupportedOperationException("Unknown uri:" + uri);
		}

		}
	}

	private SelectionBuilder buildSimpleSelection(Uri uri) {
		// TODO Auto-generated method stub
		final SelectionBuilder builder = new SelectionBuilder();
		final int match = sUriMatcher.match(uri);
		switch (match) {
		case PLANS: {
			return builder.table(Tables.PLANS);
		}
		default: {
			throw new UnsupportedOperationException("Unknown uri: " + uri);
		}
		}
	}


	public ContentProviderResult[] applyBatch(
			ArrayList<ContentProviderOperation> operations)
			throws OperationApplicationException {
		final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
		db.beginTransaction();
		try {
			final int numOperations = operations.size();
			final ContentProviderResult[] results = new ContentProviderResult[numOperations];
			for (int i = 0; i < numOperations; i++) {
				results[i] = operations.get(i).apply(this, results, i);
			}
			db.setTransactionSuccessful();
			return results;
		} finally {
			db.endTransaction();
		}
	}
}
